home *** CD-ROM | disk | FTP | other *** search
- /*
- * RevRINIT.c - INIT to cause RevRdist to be run at system boot time
- */
- #include "RevRdist.h"
- #include <asm.h>
- #include "volops.h"
-
- /*
- * Structure of startup header
- */
- struct startp {
- Integer startid; /* id word */
- ProcPtr entryp; /* boot code entry point */
- Integer version; /* startup version */
- Integer azero;
- Str15 sysname; /* name of system resource file */
- Str15 shellname; /* name of system shell */
- Str15 debuggername; /* name of debugger file */
- Str15 disassmname; /* name of disassembler file */
- Str15 startscreen; /* name of startup screen image file */
- Str15 startappl; /* name of first program to run */
- Str15 scrapname; /* name of disk scrap file */
- Integer fcbcnt; /* number of file control blocks */
- Integer eventcnt; /* size of event queue */
- Longint heapsize1; /* heap size on 128k system */
- Longint reserved;
- Longint heapsize2; /* heap size on 512k system */
- };
- typedef struct startp startp_t;
- #define STARTID 'LK' /* correct value of id word */
-
- struct bootstuff {
- long unknown;
- startp_t *bootptr;
- };
- extern struct bootstuff BootTmp8 : 0xb36;
-
- typedef unsigned long u_long;
-
- #define COPYPS(s,d) BlockMove (s, d, (Size)(((s)[0]) + 1)) /* copy pas. str */
- #define ZERO(s) memset ((char *)&(s), 0, sizeof (s)) /* zero struct */
-
- /*
- * Prototypes
- */
- static OSErr doFudge (Str31,int);
- static OSErr findAppl (Str31);
- static OSErr getPrefs (Str31, long, StringHandle *, Str31, Str31, Str31, Str31, Str31, Str31);
- static OSErr getFromAppl (Str31, Str31, long *);
- extern void main (Handle);
- extern void ShowINIT (Integer);
- static void start (void);
-
- /*
- * Globals for routines in volops.c
- */
- Integer BootVol;
- StringPtr Clue0;
- Integer ClueID;
- Boolean Quit;
-
- /*
- *=========================================================================
- * start () - routine given control by INIT 31
- * Must be first code in first file in project
- *=========================================================================
- */
- static
- void
- start ()
- {
- asm
- {
- move.l a0,-(sp) /* pass handle to selves to main */
- move.l (a0),a4 /* set A4 to allow refs to globals */
- jsr main /* call main routine */
- move.l (sp)+,a0 /* pop arg to restore stack */
- }
- }
-
-
- extern unsigned char ApplScratch[12] : 0xa78;
-
- /*
- *=========================================================================
- * main - main sequence
- *=========================================================================
- */
- void
- main (self)
- Handle self;
- {
- register OSErr result;
- StringHandle master; /* name of master folder on server */
- Str31 applName; /* name of RevRdist application */
- Str31 prefName; /* name of prefs file */
- Str31 zoneName; /* server zone name */
- Str31 serverName; /* name of server to use */
- Str31 userName; /* name to log on to server as */
- Str31 serverVol; /* server volume to user */
- Str31 password; /* user password on server */
- Str31 startName; /* "Set Startup" name to force */
- Str255 s; /* string temp */
- Integer volref; /* dummy for GetVol */
- long RRflags; /* RevRdist flags */
- StringPtr sp; /* temp */
- AFPVolMountInfo mi; /* mounting info for accessMaster */
-
- HLock (self);
- SetResLoad (true); /* should already be true, but ... */
- result = (FSFCBLen <= 0); /* make sure HFS */
- startName[0] = 0;
- RRflags = 0;
- Quit = false;
- /*
- * Find the RevRdist application
- */
- if (result == 0)
- result = findAppl (applName);
- /*
- * Get run flags and the name of the preferences file from RevRdist
- */
- if (result == 0)
- result = getFromAppl (applName, prefName, &RRflags);
- /*
- * Extract the preferences & check if it's time to run
- */
- master = 0;
- if (result == 0)
- result = getPrefs (prefName, RRflags, &master,
- serverVol, zoneName, serverName, userName, password,
- startName);
- /*
- * Set the shell, if specified, whether we run RevRdist or not
- */
- if (startName[0])
- (void) doFudge (startName, 0);
- /*
- * If RevRdist is not going to mount the server, we should try
- */
- if (result == 0 && (RRflags & PF_NOMOUNT))
- {
- GetVol (s, &BootVol);
- COPYPS (*master, s);
- ZERO(mi);
- mi.length = sizeof(mi);
- mi.media = AppleShareMediaType;
- sp = (StringPtr)mi.AFPData;
- if (zoneName[0] == 0)
- {
- zoneName[1] = '*'; /* supply default zone name */
- zoneName[0] = 1;
- }
-
- #define COPYPREF(nn,ee) \
- COPYPS(nn, sp); \
- mi.ee = sp - (StringPtr)(&mi); \
- sp += 32;
-
- COPYPREF(zoneName, zoneNameOffset);
- COPYPREF(serverName, serverNameOffset);
- COPYPREF(serverVol, volNameOffset);
- COPYPREF(userName, userNameOffset);
- COPYPREF(password, userPasswordOffset);
- #undef COPYPREF
-
- result = accessMaster (s, &mi);
- }
- if (master)
- DisposHandle ((Handle) master);
- if (result == 0 && Quit == false)
- result = doFudge (applName,1);
- HUnlock (self);
- }
-
-
-
- /*
- *=========================================================================
- * doFudge (ap,flag) - modify memory copy of boot blocks to make RevRdist
- * application the "startup" application
- * entry: ap = name of RevRdist
- * flag indicates whether ApplScratch should be munged also
- * returns: 0 if all went well,
- * <> 0 if boot blocks area looks fishy
- *=========================================================================
- */
- static
- OSErr
- doFudge (ap, flag)
- Str31 ap;
- int flag;
- {
- register unsigned char c;
- register startp_t * startp; /* ptr to boot param block */
- long * lp; /* pts into ApplScratch */
-
- /*
- * Locate the memory copy of the system startup information
- * Check that it appears intact.
- * Replace the startup program name with RevRdist name
- */
- startp = (startp_t *)((long)MemTop / 2);
-
- if (startp->startid != STARTID) {
- startp = BootTmp8.bootptr;
- if (startp->startid != STARTID)
- return 1;
- }
- if (startp->azero)
- return 2;
- #define CHECK(w, e) if ((c = startp->w[0]) == 0 || c > 15) return (e)
- CHECK (sysname, 3);
- CHECK (shellname, 4);
- CHECK (debuggername, 5);
- CHECK (disassmname, 6);
- CHECK (startscreen, 7);
- CHECK (startappl, 8);
- CHECK (scrapname, 9);
- #undef CHECK
- if (startp->fcbcnt < 0)
- return 10;
- if (startp->eventcnt < 0)
- return 11;
- COPYPS (ap, startp->startappl);
- if (flag)
- {
- lp = (long *)(ApplScratch + 8);
- lp[0] = CREATOR; /* leave a "note" for RevRdist */
- }
- return 0;
- }
-
-
-
- /*
- *=========================================================================
- * findAppl (ap) - locate RevRdist application and return its name
- * entry: ap = Str31 to contain name
- * returns: 0 on success, else OSErr
- *=========================================================================
- */
- static
- OSErr
- findAppl (ap)
- Str31 ap;
- {
- OSErr error;
- int i;
- Str255 name;
- CInfoPBRec ci;
- unsigned long besttime;
-
- /*
- * Search the current directory to find a file with the correct
- * type (APPL) and CREATOR and the most recent mod time.
- */
- besttime = 0;
- ZERO (ci);
- ci.hFileInfo.ioNamePtr = name;
- for (i = 1, error = 0; ! error; i++)
- {
- name[0] = 0;
- ci.hFileInfo.ioDirID = 0;
- ci.hFileInfo.ioFDirIndex = i;
- error = PBGetCatInfo (&ci, false);
- if (error == 0)
- {
- if (ci.hFileInfo.ioFlAttrib & 0x10)
- continue; /* if directory */
- if (ci.hFileInfo.ioFlFndrInfo.fdType == 'APPL'
- && ci.hFileInfo.ioFlFndrInfo.fdCreator == CREATOR)
- {
- if (name[0] > 15)
- continue; /* ignore if unacceptable name */
- if (ci.hFileInfo.ioFlMdDat < besttime)
- continue; /* if older than current best */
- besttime = ci.hFileInfo.ioFlMdDat;
- COPYPS (name, ap);
- }
- }
- }
- if (besttime)
- error = 0; /* no error if any candidate found */
- return error;
- }
-
-
-
- /*
- *=========================================================================
- * getPrefs (pf, fl, mf, sv, zn, sn, un, pw, an) - extract info from preferences file
- * entry: pf = name of preferences file
- * fl = RevRdist run flags
- * mf = ptr to handle for master folder name string
- * sv = buf for server volume name
- * zn = buf for server zone
- * sn = buf for server name
- * un = buf for user name
- * pw = buf for password
- * an = buf for startup application
- * returns: 0 if preferences found and set,
- * 1 if not time to run
- * other <> 0 on error
- *=========================================================================
- */
- static
- OSErr
- getPrefs (pf, fl, mf, sv, zn, sn, un, pw, an)
- Str31 pf;
- long fl;
- StringHandle * mf;
- Str31 sv;
- Str31 zn;
- Str31 sn;
- Str31 un;
- Str31 pw;
- Str31 an;
- {
- Integer curref; /* current resource file */
- OSErr error;
- Handle h; /* handle to resources */
- int i; /* temp counter */
- int len; /* temp string length */
- u_long interval; /* running interval from prefs */
- u_long now; /* current time */
- Handle ph; /* handle to interval resource */
- Integer refnum; /* resource file refnum */
- StringPtr sp; /* ptr to resource strings */
- Integer theID; /* dummy for GetResInfo */
- ResType theType; /* dummy for GetResInfo */
- Integer vrefnum; /* resource file vrefnum */
- HParamBlockRec pb; /* HFS parameter block */
-
- /*
- * Extract the various preference resources from the preferences file
- */
- error = 0;
- an[0] = 0;
- curref = CurResFile ();
- refnum = OpenRFPerm (pf, 0, fsRdWrPerm);
- if (refnum == -1)
- return ResError ();
- /*
- * Get the optional name of the startup application, whether anything
- * else goes right or not
- */
- h = Get1Resource ('STR ', STR_START); /* try prefs first */
- if (!h)
- {
- UseResFile (curref); /* then try inside ourselves */
- h = Get1Resource ('STR ', STR_START);
- UseResFile (refnum);
- }
- if (h)
- {
- sp = (StringPtr)(*h);
- if (sp[0] < 16)
- COPYPS (sp, an);
- ReleaseResource (h);
- }
- if (!(fl & PF_TOUCH))
- {
- /*
- * Get the interval.
- * If it's not time to run yet, exit
- */
- ph = Get1Resource (TYPE_LONG, TIME_INTERVAL);
- if (!ph)
- goto resexit;
- if (SizeResource (ph) < sizeof (interval))
- {
- error = resNotFound;
- goto exit;
- }
- interval = *(u_long *)(*ph);
- GetDateTime (&now);
- error = GetVRefNum (refnum, &vrefnum);
- if (error)
- goto exit;
- ZERO (pb);
- pb.fileParam.ioNamePtr = pf;
- pb.fileParam.ioVRefNum = vrefnum;
- error = PBHGetFInfo (&pb, false);
- if (error)
- goto exit;
- if ((u_long) pb.fileParam.ioFlMdDat + interval > now)
- {
- error = 1; /* not time yet */
- goto exit;
- }
- }
- /*
- * Go ahead and extract the remaining preference strings
- */
- h = Get1Resource ('STR ', STR_MASTF);
- if (!h)
- goto resexit;
- /*
- * The master folder STR is a complete path.
- * We also want the first component.
- */
- sp = (StringPtr)(*h);
- len = sp[0];
- if (len > 32)
- len = 32;
- for (i = 1; i < len; i++)
- if (sp[i] == ':')
- break;
- else
- sv[i] = sp[i];
- if (i > 31)
- goto badstring;
- sv[0] = i - 1;
- *mf = (StringHandle) h;
- DetachResource(h);
-
- h = Get1Resource ('STR ', STR_ZONE);
- if (h) /* zone is optional */
- {
- sp = (StringPtr)(*h);
- if (sp[0] > 31)
- goto badstring;
- COPYPS (sp, zn);
- ReleaseResource (h);
- }
- else
- zn[0] = 0;
-
- h = Get1Resource ('STR ', STR_SRVR);
- if (!h)
- goto resexit;
- sp = (StringPtr)(*h);
- if (sp[0] > 31)
- goto badstring;
- COPYPS (sp, sn);
- ReleaseResource (h);
-
- h = Get1Resource ('STR ', STR_USER);
- if (h) /* user is optional */
- {
- sp = (StringPtr)(*h);
- if (sp[0] > 31)
- goto badstring;
- COPYPS (sp, un);
- ReleaseResource (h);
- }
- else
- un[0] = 0;
-
- h = Get1Resource ('STR ', STR_PASS);
- if (h) /* password is optional */
- {
- sp = (StringPtr)(*h);
- if (sp[0] > 31)
- goto badstring;
- COPYPS (sp, pw);
- ReleaseResource (h);
- }
- else
- pw[0] = 0;
- if (!(fl & PF_TOUCH))
- {
- /*
- * "Change" a resource to update the mod time so we don't
- * get in a boot/run/reboot loop
- */
- ChangedResource (ph);
- WriteResource (ph);
- }
- goto exit;
-
- resexit:
- error = ResError ();
- if (!error)
- error = resNotFound;
- goto exit;
-
- badstring:
- ReleaseResource (h);
- error = bdNamErr;
-
- exit:
- if (ph)
- ReleaseResource (ph);
- if (refnum != curref)
- {
- (void) CloseResFile (refnum);
- (void) UseResFile (curref);
- }
- return error;
- }
-
-
-
-
- /*
- *=========================================================================
- * getFromAppl (ap, pf, fl) - extract flags and preferences file name from appl file
- * entry: ap = name of RevRdist application in current directory
- * pf = buf for prefs file name
- * fl = ptr to flags long word
- * returns 0 if pf set,
- * <> 0 on error
- *=========================================================================
- */
- static
- OSErr
- getFromAppl (ap, pf, fl)
- Str31 ap;
- Str31 pf;
- long *fl;
- {
- Integer curref; /* current resource file */
- OSErr error;
- Handle h;
- Integer refnum; /* resource file refnum */
- StringPtr sp;
-
- /*
- * We just extract the STR_PREFS resource from the RevRdist
- * application to get the name of its default preferences file.
- */
- error = 0;
- curref = CurResFile ();
- refnum = OpenRFPerm (ap, 0, fsRdPerm);
- if (refnum == -1)
- return (ResError ());
- h = Get1Resource ('STR ', STR_PREFS);
- if (h)
- {
- sp = (StringPtr)(*h);
- if (sp[0] < 32)
- {
- COPYPS (sp, pf);
- ShowINIT (RSRC_INITICON);
- }
- else
- error = bdNamErr;
- ReleaseResource (h);
- }
- else
- error = ResError ();
- if (error == 0)
- {
- h = Get1Resource ('Long', FLAG_PARM);
- if (h)
- {
- if (SizeResource(h) == sizeof(*fl))
- BlockMove (*h, (Ptr)fl, sizeof (*fl));
- ReleaseResource (h);
- }
- }
- if (refnum != curref)
- {
- (void) CloseResFile (refnum);
- (void) UseResFile (curref);
- }
- return error;
- }
-
- /*
- * dummy panic routine
- */
- void
- panic (Boolean f, enum error_e id, StringPtr sp, ...)
- {
- Quit = true;
- }